
//*********************************************
//  This is Template of Cosmic Ray Generator
//                                  author:Ruiting
//

#ifndef _MyBaseGen_H_
#define _MyBaseGen_H_

#include "G4ThreeVector.hh"
#include "G4Types.hh"
#include "G4String.hh"
#include "G4Event.hh"
#include "yaml-cpp/yaml.h"
#include <vector>
#include <string>
#include <cmath>
#include <algorithm>

using PosAndMom = std::pair<G4ThreeVector, G4ThreeVector>;

class MyBaseGen
{
public:
    MyBaseGen();
    virtual ~MyBaseGen();

    virtual void Initialize(YAML::Node){}
    virtual void GeneratePrimaryVertex(G4Event*){}

    inline void SetParticle(G4String Particle){m_Particle = Particle;}
    inline void SetParticleEnergy(G4double ParticleEnergy){m_ParticleEnergy = ParticleEnergy;}
    inline void SetParticlePosition(G4ThreeVector ParticlePosition){m_ParticlePosition = ParticlePosition;}
    inline void SetParticlePolarization(G4ThreeVector ParticlePolarization){m_ParticlePolarization = ParticlePolarization;}
    inline void SetParticleMomentumDirection(G4ThreeVector ParticleMomentumDirection){m_ParticleMomentumDirection = ParticleMomentumDirection;}
    inline void SetTypeFlag(G4int TypeFlag){m_TypeFlag = TypeFlag;}
    inline void SetValid(G4bool valid){m_Valid = valid;}

    inline G4String GetPGType(){return m_PGType;}
    inline G4String GetParticle(){return m_Particle;}
    inline G4double GetParticleEnergy(){return m_ParticleEnergy;}
    inline G4ThreeVector GetParticlePosition(){return m_ParticlePosition;}
    inline G4ThreeVector GetParticlePolarization(){return m_ParticlePolarization;}
    inline G4ThreeVector GetParticleMomentumDirection(){return m_ParticleMomentumDirection;}
    inline G4int GetTypeFlag(){return m_TypeFlag;}
    inline G4bool GetValid(){return m_Valid;}
    virtual inline G4bool IfNeedPolPhot(){return false;}
    inline G4int GetGenerateNumber(){return m_GenNumber;}

    G4ThreeVector ConvertArrayToV3(YAML::Node);
    PosAndMom GenPosAndMomDir();
    static G4ThreeVector MomDir4Pi();
    inline static bool mySort(double i, double j){return (i < j);}

protected:
    G4String m_PGType;
    G4String m_ClassName;
    G4String m_Particle;
    G4double m_ParticleEnergy; //Unit: MeV
    G4ThreeVector m_ParticlePosition;
    G4ThreeVector m_ParticlePolarization;
    G4ThreeVector m_ParticleMomentumDirection;
    G4int m_TypeFlag;
    G4int m_GenNumber;
    G4int m_EvtFlag;
    G4bool m_Valid;

private:
    G4double m_BoxLength;
    G4double m_BallRadius;
};

#endif